/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.stx.xhb.customwaterview.components;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorProperty;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.app.Context;

import static ohos.agp.animation.Animator.INFINITE;

/**
 * 自定义仿支付宝蚂蚁森林水滴View
 *
 * @since 2021-06-08
 */
public class WaterView extends Component implements Component.DrawTask,
        Component.EstimateSizeListener, Component.BindStateChangedListener {
    private static final float STROKE_WIDTH = 0.5f;
    private static final int TEXT_SIZE = 48;
    private static final int RADIUS = 70;

    /**
     * 水滴球动画偏移量
     */
    private static final int OFFSET = 50;

    private Paint paint;
    private AnimatorProperty mAnimator;
    /**
     * 文字颜色
     */
    private int textColor = Color.getIntColor("#69c78e");
    /**
     * 水滴填充颜色
     */
    private int waterColor = Color.getIntColor("#c3f593");
    /**
     * 球描边颜色
     */
    private int storkeColor = Color.getIntColor("#69c78e");
    /**
     * 描边线条宽度
     */
    private float strokeWidth = STROKE_WIDTH;
    /**
     * 文字字体大小
     */
    private float textSize = TEXT_SIZE;
    /**
     * 水滴球半径
     */
    private int mRadius = RADIUS;

    /**
     * 圆球文字内容
     */
    private String textContent = "";
    /**
     * 是否自动开始动画
     */
    private boolean isAutoShowAnimate = false;

    /**
     * WaterView
     *
     * @param context
     * @param textContent
     */
    public WaterView(Context context, String textContent) {
        super(context);
        this.textContent = textContent;
        init();
    }

    /**
     * WaterView
     *
     * @param context
     * @param attrs
     */
    public WaterView(Context context, AttrSet attrs) {
        super(context, attrs);
        init();
    }

    /**
     * WaterView
     *
     * @param context
     * @param attrs
     * @param defStyleAttr
     */
    public WaterView(Context context, AttrSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        addDrawTask(this);
        setBindStateChangedListener(this);
        setEstimateSizeListener(this);
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        drawCircleView(canvas);
    }

    @Override
    public boolean onEstimateSize(int widthEstimateConfig, int heightEstimateConfig) {
        final int num2 = 2;
        int width = (int) (num2 * (mRadius + strokeWidth));
        int height = (int) (num2 * (mRadius + strokeWidth));
        setEstimatedSize(
                Component.EstimateSpec.getChildSizeWithMode(width, width, Component.EstimateSpec.NOT_EXCEED),
                Component.EstimateSpec.getChildSizeWithMode(height, height, Component.EstimateSpec.NOT_EXCEED));
        return true;
    }

    @Override
    public void onComponentBoundToWindow(Component component) {
        if (isAutoShowAnimate) {
            start();
        }
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {
        stop();
    }

    /**
     * 是否自动开始动画
     *
     * @param isAuto
     */
    public void setAutoShowAnimate(boolean isAuto) {
        this.isAutoShowAnimate = isAuto;
    }

    private void drawCircleView(Canvas canvas) {
        // 圆球
        paint.setColor(new Color(waterColor));
        paint.setStyle(Paint.Style.FILL_STYLE);
        canvas.drawCircle(mRadius, mRadius, mRadius, paint);

        // 描边
        paint.setColor(new Color(storkeColor));
        paint.setStyle(Paint.Style.STROKE_STYLE);
        paint.setStrokeWidth(strokeWidth);
        canvas.drawCircle(mRadius, mRadius, mRadius + strokeWidth, paint);

        // 圆球文字
        paint.setTextSize((int) textSize);
        paint.setColor(new Color(textColor));
        paint.setStyle(Paint.Style.FILL_STYLE);
        drawVerticalText(canvas, mRadius, mRadius, textContent);
    }

    private void drawVerticalText(Canvas canvas, float centerX, float centerY, String text) {
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        final int num2 = 2;
        float baseLine = -(fontMetrics.ascent + fontMetrics.descent) / num2;
        float textWidth = paint.measureText(text);
        float startX = centerX - textWidth / num2;
        float endY = centerY + baseLine;
        canvas.drawText(paint, text, startX, endY);
    }

    /**
     * 开始动画
     */
    public void start() {
        if (mAnimator == null) {
            final int duration = 3500;
            mAnimator = createAnimatorProperty();
            mAnimator.moveFromY(getBottom()).moveToY(getBottom() + OFFSET).setDuration(duration)
                    .setCurveType(Animator.CurveType.CYCLE)
                    .setLoopedCount(INFINITE);
            mAnimator.start();
        } else if (!mAnimator.isRunning()) {
            mAnimator.start();
        }
    }

    /**
     * 停止动画
     */
    public void stop() {
        if (mAnimator != null) {
            mAnimator.cancel();
            mAnimator = null;
        }
    }
}
